[iOS 8] HealthKitを実装する(3) HealthStoreからデータを取得する
HealthStoreからデータを取得する実装例
アプリケーションがHealthStoreからデータを取得する場合、永続化する場合と同様にユーザーの許可が必要です。
以下はHealthStoreに永続化された体温を全件取得するサンプルです。
/** HealthStoreから引数に渡されたデータ型に一致する健康情報を全件取得します。 :param: unit 健康情報の単位型 :param: type 取得したいデータ型 :param: completion 取得完了時に実行される処理 */ func findAllHealthValueWithUnit(unit: HKUnit!, type: HKQuantityType!, completion: ((query: HKSampleQuery!, responseObj: [AnyObject]!, error: NSError!) -> Void)) { let healthStore = HKHealthStore() // HealthStoreのデータを全件取得するHKSampleQueryを返却します。 let findAllQuery : () -> HKSampleQuery = { return HKSampleQuery(sampleType: type, predicate: nil, limit: 0, sortDescriptors: nil, resultsHandler: completion) } let types: NSSet! = NSSet(object: type) let authStatus:HKAuthorizationStatus = healthStore.authorizationStatusForType(type) if authStatus == .SharingAuthorized { healthStore.executeQuery(findAllQuery()) } else { // 体温型のデータをHealthStoreから取得するために、ユーザーへ許可を求めます。 // 許可されたデータのみ、アプリケーションからHealthStoreへ読み込みする権限が与えられます。 // ヘルスケアの[ソース]タブ画面がモーダルで表示されます。 // 第1引数に指定したNSSet!型のshareTypesの書き込み許可を求めます。 // 第2引数に指定したNSSet!型のreadTypesの読み込み許可を求めます。 healthStore.requestAuthorizationToShareTypes(types, readTypes: types) { success, error in if error != nil { NSLog(error.description); return } if success { NSLog("取得可能"); // 引数に指定されたクエリーを実行します healthStore.executeQuery(findAllQuery()) } } } } func findAllBodyTemperature() { // 体温の単位を生成します。単位は℃(摂氏)です。 let btUnit: HKUnit! = HKUnit.degreeCelsiusUnit() // 体温情報の型を生成します。 let btType: HKQuantityType! = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierBodyTemperature) // 取得処理完了時に非同期で呼び出されます。 findAllHealthValueWithUnit(btUnit, type: btType , { query, responseObj, error in if error != nil { NSLog(error.description) return } // 取得した結果がresponseObjに格納されています。 // アプリケーションで使用する場合、[AnyObject]!型のresponseObjを必要な型にキャストする必要があります。 NSLog("resultObj : \(responseObj)") let btUnit: HKUnit = HKUnit.degreeCelsiusUnit() var btResults: [Double!] = [] // HealthStoreで使用していた型から体温の値へと復元します。 for bodyTemperature: HKQuantitySample in responseObj as [HKQuantitySample] { // 値を取得します。 let btQuantity: HKQuantity! = bodyTemperature.quantity let btResult: Double = btQuantity.doubleValueForUnit(btUnit) btResults.append(btResult); } NSLog("values : \(btResults)") }) }
同じく実行される順に、各処理を解説します。
findAllBodyTemperature()
体温データの情報を元にfindAllHealthValueWithUnit(unit: HKUnit!, type: HKQuantityType!, completion: ((query: HKSampleQuery!, responseObj: [AnyObject]!, error: NSError!) -> Void))を呼び出しています。取得したいデータによってこちらのメソッドを変えると良いでしょう。
findAllHealthValueWithUnit(unit: HKUnit!, type: HKQuantityType!, completion: ((query: HKSampleQuery!, responseObj: [AnyObject]!, error: NSError!) -> Void))
一連の取得処理を実行します。
findAllQuery() -> HKSampleQuery
HealthStoreへデータを問い合わせるためのクエリーを返却します。
HKSampleQueryのコンストラクター引数を変更することによって、取得するデータの指定・特定条件の絞り込み・取得件数の制御・ソートが行えます。
今回は絞り込み条件なし、取得件数は全件(limit0は全件取得)、ソート条件はなしで実行しています。
クエリーの実行完了時にcompletionメソッドが実行されます。
completion(query: HKSampleQuery!, responseObj: [AnyObject]!, error: NSError!)
クエリーの結果を取得できます。
取得した結果は第2引数に[AnyObject]!型で渡されます。
こちらの配列から任意の型へキャストすることによって、アプリケーションで使用することが可能です。
今回はHKQuantitySampleの配列から、体温型を指定してDouble型へキャストしています。